<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>珠峰架构师成长计划</title>
    <link rel="stylesheet" type="text/css" href="../static/css/main.css">
</head>
<body>
<div class="nav">
    <div class="logo">
        
            珠峰架构师成长计划
        
    </div>
<ul><li><a href="../index.html">0.Async</a></li><li><a href="../html/0.editor.html">0.editor</a></li><li><a href="../html/0.module.html">0.module</a></li><li><a href="../html/1.ES2015.html">1.ES2015</a></li><li><a href="../html/2.Promise.html">2.Promise</a></li><li><a href="../html/3.Node.html">3.Node</a></li><li><a href="../html/4.NodeInstall.html">4.NodeInstall</a></li><li><a href="../html/5.REPL.html">5.REPL</a></li><li><a href="../html/6.NodeCore.html">6.NodeCore</a></li><li><a href="../html/7.module&NPM.html">7.module&NPM</a></li><li><a href="../html/8.Encoding.html">8.Encoding</a></li><li><a href="../html/9.Buffer.html">9.Buffer</a></li><li><a href="../html/10.fs.html">10.fs</a></li><li><a href="../html/11.Stream-1.html">11.Stream-1</a></li><li><a href="../html/11.Stream-2.html">11.Stream-2</a></li><li><a href="../html/11.Stream-3.html">11.Stream-3</a></li><li><a href="../html/11.Stream-4.html">11.Stream-4</a></li><li><a href="../html/12-Network-2.html">12-Network-2</a></li><li><a href="../html/12.NetWork-3.html">12.NetWork-3</a></li><li><a href="../html/12.Network-1.html">12.Network-1</a></li><li><a href="../html/13.tcp.html">13.tcp</a></li><li><a href="../html/14.http-1.html">14.http-1</a></li><li><a href="../html/14.http-2.html">14.http-2</a></li><li><a href="../html/15.compress.html">15.compress</a></li><li><a href="../html/16.crypto.html">16.crypto</a></li><li><a href="../html/17.process.html">17.process</a></li><li><a href="../html/18.yargs.html">18.yargs</a></li><li><a href="../html/19.cache.html">19.cache</a></li><li><a href="../html/20.action.html">20.action</a></li><li><a href="../html/21.https.html">21.https</a></li><li><a href="../html/22.cookie.html">22.cookie</a></li><li><a href="../html/23.session.html">23.session</a></li><li><a href="../html/24.express-1.html">24.express-1</a></li><li><a href="../html/24.express-2.html">24.express-2</a></li><li><a href="../html/24.express-3.html">24.express-3</a></li><li><a href="../html/24.express-4.html">24.express-4</a></li><li><a href="../html/25.koa-1.html">25.koa-1</a></li><li><a href="../html/26.webpack-1-basic.html">26.webpack-1-basic</a></li><li><a href="../html/26.webpack-2-optimize.html">26.webpack-2-optimize</a></li><li><a href="../html/26.webpack-3.tapable.html">26.webpack-3.tapable</a></li><li><a href="../html/26.webpack-4-AST.html">26.webpack-4-AST</a></li><li><a href="../html/26.webpack-5-source.html">26.webpack-5-source</a></li><li><a href="../html/26.webpack-6-loader.html">26.webpack-6-loader</a></li><li><a href="../html/26.webpack-7-plugin.html">26.webpack-7-plugin</a></li><li><a href="../html/26.webpack-8-hand.html">26.webpack-8-hand</a></li><li><a href="../html/27.react-1.html">27.react-1</a></li><li><a href="../html/27.react-2.html">27.react-2</a></li><li><a href="../html/27.react-3.html">27.react-3</a></li><li><a href="../html/27.react-4-immutable.html">27.react-4-immutable</a></li><li><a href="../html/27.react-5-react-dom-diff.html">27.react-5-react-dom-diff</a></li><li><a href="../html/27.react-6.html">27.react-6</a></li><li><a href="../html/28.react-mobx.html">28.react-mobx</a></li><li><a href="../html/28.redux-0.html">28.redux-0</a></li><li class="active"><a href="../html/28.redux-1.html">28.redux-1</a></li><li><a href="../html/28.redux-2-中间件.html">28.redux-2-中间件</a></li><li><a href="../html/28.redux-3-saga.html">28.redux-3-saga</a></li><li><a href="../html/28.redux-jwt-back.html">28.redux-jwt-back</a></li><li><a href="../html/28.redux-jwt-front.html">28.redux-jwt-front</a></li><li><a href="../html/29.mongodb-1.html">29.mongodb-1</a></li><li><a href="../html/29.mongodb-2.html">29.mongodb-2</a></li><li><a href="../html/29.mongodb-3.html">29.mongodb-3</a></li><li><a href="../html/29.mongodb-4.html">29.mongodb-4</a></li><li><a href="../html/29.mongodb-5.html">29.mongodb-5</a></li><li><a href="../html/29.mongodb-6.html">29.mongodb-6</a></li><li><a href="../html/30.cms-1-mysql.html">30.cms-1-mysql</a></li><li><a href="../html/30.cms-2-mysql.html">30.cms-2-mysql</a></li><li><a href="../html/30.cms-3-mysql.html">30.cms-3-mysql</a></li><li><a href="../html/30.cms-4-egg.html">30.cms-4-egg</a></li><li><a href="../html/30.cms-5-api.html">30.cms-5-api</a></li><li><a href="../html/30.cms-6-roadhog.html">30.cms-6-roadhog</a></li><li><a href="../html/30.cms-7-umi.html">30.cms-7-umi</a></li><li><a href="../html/30.cms-8-dva.html">30.cms-8-dva</a></li><li><a href="../html/30.cms-9-dva.html">30.cms-9-dva</a></li><li><a href="../html/30.cms-10-front.html">30.cms-10-front</a></li><li><a href="../html/30.cms-11-deploy.html">30.cms-11-deploy</a></li><li><a href="../html/33.redis.html">33.redis</a></li><li><a href="../html/34.unittest.html">34.unittest</a></li><li><a href="../html/35.jwt.html">35.jwt</a></li><li><a href="../html/36.websocket-1.html">36.websocket-1</a></li><li><a href="../html/36.websocket-2.html">36.websocket-2</a></li><li><a href="../html/38.chat-api-1.html">38.chat-api-1</a></li><li><a href="../html/38.chat-api-2.html">38.chat-api-2</a></li><li><a href="../html/38.chat-3.html">38.chat-3</a></li><li><a href="../html/38.chat-api-3.html">38.chat-api-3</a></li><li><a href="../html/38.chat.html">38.chat</a></li><li><a href="../html/38.chat2.html">38.chat2</a></li><li><a href="../html/38.chat2.html">38.chat2</a></li><li><a href="../html/39.crawl-0.html">39.crawl-0</a></li><li><a href="../html/39.crawl-1.html">39.crawl-1</a></li><li><a href="../html/39.crawl-2.html">39.crawl-2</a></li><li><a href="../html/40.deploy.html">40.deploy</a></li><li><a href="../html/41.safe.html">41.safe</a></li><li><a href="../html/42.test.html">42.test</a></li><li><a href="../html/43.nginx.html">43.nginx</a></li><li><a href="../html/44.enzyme.html">44.enzyme</a></li><li><a href="../html/45.docker.html">45.docker</a></li><li><a href="../html/46.elastic.html">46.elastic</a></li><li><a href="../html/47.oauth.html">47.oauth</a></li><li><a href="../html/48.wxpay.html">48.wxpay</a></li><li><a href="../html/49.nunjucks.html">49.nunjucks</a></li><li><a href="../html/50.ketang.html">50.ketang</a></li><li><a href="../html/index.html">index</a></li><li><a href="../html/51.typescript.html">51.typescript</a></li><li><a href="../html/52.UML.html">52.UML</a></li><li><a href="../html/53.design.html">53.design</a></li><li><a href="../html/index.html">index</a></li><li><a href="../html/54.linux.html">54.linux</a></li><li><a href="../html/55.yaml.html">55.yaml</a></li><li><a href="../html/50.ketang2.html">50.ketang2</a></li><li><a href="../html/56.ts.html">56.ts</a></li><li><a href="../html/57.ts_react.html">57.ts_react</a></li><li><a href="../html/58.react-ssr.html">58.react-ssr</a></li><li><a href="../html/59.react-ssr.html">59.react-ssr</a></li></ul></div>


<div class="warpper">

    <div class="page-toc">
        <ul><li><a href="#t01. Redux应用场景">1. Redux应用场景</a></li><li><a href="#t12. Redux设计思想">2. Redux设计思想</a></li><li><a href="#t23. Redux三大原则">3. Redux三大原则</a></li><li><a href="#t34. Redux概念解析">4. Redux概念解析</a><ul><li><a href="#t44.1 Store">4.1 Store</a></li><li><a href="#t54.2 State">4.2 State</a></li><li><a href="#t64.3 Action">4.3 Action</a></li><li><a href="#t74.4 Action Creator">4.4 Action Creator</a></li><li><a href="#t84.5 store.dispatch()">4.5 store.dispatch()</a></li><li><a href="#t94.6 Reducer">4.6 Reducer</a></li></ul></li><li><a href="#t105.编写Redux">5.编写Redux</a></li><li><a href="#t116. Counter-Vanilla">6. Counter-Vanilla</a></li><li><a href="#t126. React Counter">6. React Counter</a></li><li><a href="#t137.actionCreator优化结构">7.actionCreator优化结构</a></li><li><a href="#t148.bindActionCreator">8.bindActionCreator</a></li><li><a href="#t159. combineReducers">9. combineReducers</a></li><li><a href="#t1610. react-redux">10. react-redux</a></li></ul>
    </div>
    
    <div class="content markdown-body">
        <h2 id="t01. Redux&#x5E94;&#x7528;&#x573A;&#x666F;">1. Redux&#x5E94;&#x7528;&#x573A;&#x666F; <a href="#t01. Redux&#x5E94;&#x7528;&#x573A;&#x666F;"> # </a></h2>
<ul>
<li>&#x968F;&#x7740; JavaScript &#x5355;&#x9875;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x65E5;&#x8D8B;&#x590D;&#x6742;,&#x7BA1;&#x7406;&#x4E0D;&#x65AD;&#x53D8;&#x5316;&#x7684; state &#x975E;&#x5E38;&#x56F0;&#x96BE;</li>
<li>Redux&#x7684;&#x51FA;&#x73B0;&#x5C31;&#x662F;&#x4E3A;&#x4E86;&#x89E3;&#x51B3;state&#x91CC;&#x7684;&#x6570;&#x636E;&#x95EE;&#x9898;</li>
<li>&#x5728;React&#x4E2D;&#xFF0C;&#x6570;&#x636E;&#x5728;&#x7EC4;&#x4EF6;&#x4E2D;&#x662F;&#x5355;&#x5411;&#x6D41;&#x52A8;&#x7684;</li>
<li>&#x6570;&#x636E;&#x4ECE;&#x4E00;&#x4E2A;&#x65B9;&#x5411;&#x7236;&#x7EC4;&#x4EF6;&#x6D41;&#x5411;&#x5B50;&#x7EC4;&#x4EF6;(&#x901A;&#x8FC7;props)&#xFF0C;&#x7531;&#x4E8E;&#x8FD9;&#x4E2A;&#x7279;&#x5F81;&#xFF0C;&#x4E24;&#x4E2A;&#x975E;&#x7236;&#x5B50;&#x5173;&#x7CFB;&#x7684;&#x7EC4;&#x4EF6;&#xFF08;&#x6216;&#x8005;&#x79F0;&#x4F5C;&#x5144;&#x5F1F;&#x7EC4;&#x4EF6;&#xFF09;&#x4E4B;&#x95F4;&#x7684;&#x901A;&#x4FE1;&#x5C31;&#x6BD4;&#x8F83;&#x9EBB;&#x70E6;</li>
</ul>
<p><img src="http://img.zhufengpeixun.cn/redux-wrong.png" alt="redux-wrong"></p>
<h2 id="t12. Redux&#x8BBE;&#x8BA1;&#x601D;&#x60F3;">2. Redux&#x8BBE;&#x8BA1;&#x601D;&#x60F3; <a href="#t12. Redux&#x8BBE;&#x8BA1;&#x601D;&#x60F3;"> # </a></h2>
<ul>
<li>Redux&#x662F;&#x5C06;&#x6574;&#x4E2A;&#x5E94;&#x7528;&#x72B6;&#x6001;&#x5B58;&#x50A8;&#x5230;&#x5230;&#x4E00;&#x4E2A;&#x5730;&#x65B9;&#xFF0C;&#x79F0;&#x4E3A;<code>store</code></li>
<li>&#x91CC;&#x9762;&#x4FDD;&#x5B58;&#x4E00;&#x68F5;&#x72B6;&#x6001;&#x6811;<code>state tree</code></li>
<li>&#x7EC4;&#x4EF6;&#x53EF;&#x4EE5;&#x6D3E;&#x53D1;<code>dispatch</code>&#x884C;&#x4E3A;<code>action</code>&#x7ED9;<code>store</code>,&#x800C;&#x4E0D;&#x662F;&#x76F4;&#x63A5;&#x901A;&#x77E5;&#x5176;&#x5B83;&#x7EC4;&#x4EF6;</li>
<li>&#x5176;&#x5B83;&#x7EC4;&#x4EF6;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x8BA2;&#x9605;store&#x4E2D;&#x7684;&#x72B6;&#x6001;(state)&#x6765;&#x5237;&#x65B0;&#x81EA;&#x5DF1;&#x7684;&#x89C6;&#x56FE;. </li>
</ul>
<p><img src="http://img.zhufengpeixun.cn/redux-flow.png" alt="redux-flow"></p>
<h2 id="t23. Redux&#x4E09;&#x5927;&#x539F;&#x5219;">3. Redux&#x4E09;&#x5927;&#x539F;&#x5219; <a href="#t23. Redux&#x4E09;&#x5927;&#x539F;&#x5219;"> # </a></h2>
<ul>
<li>&#x6574;&#x4E2A;&#x5E94;&#x7528;&#x7684; state &#x88AB;&#x50A8;&#x5B58;&#x5728;&#x4E00;&#x68F5; object tree &#x4E2D;&#xFF0C;&#x5E76;&#x4E14;&#x8FD9;&#x4E2A; object tree &#x53EA;&#x5B58;&#x5728;&#x4E8E;&#x552F;&#x4E00;&#x4E00;&#x4E2A; store &#x4E2D;</li>
<li>State &#x662F;&#x53EA;&#x8BFB;&#x7684;&#xFF0C;&#x60DF;&#x4E00;&#x6539;&#x53D8; state &#x7684;&#x65B9;&#x6CD5;&#x5C31;&#x662F;&#x89E6;&#x53D1; action&#xFF0C;action &#x662F;&#x4E00;&#x4E2A;&#x7528;&#x4E8E;&#x63CF;&#x8FF0;&#x5DF2;&#x53D1;&#x751F;&#x4E8B;&#x4EF6;&#x7684;&#x666E;&#x901A;&#x5BF9;&#x8C61;
&#x4F7F;&#x7528;&#x7EAF;&#x51FD;&#x6570;&#x6765;&#x6267;&#x884C;&#x4FEE;&#x6539;&#xFF0C;&#x4E3A;&#x4E86;&#x63CF;&#x8FF0;action&#x5982;&#x4F55;&#x6539;&#x53D8;state tree &#xFF0C;&#x4F60;&#x9700;&#x8981;&#x7F16;&#x5199; reducers</li>
<li>&#x5355;&#x4E00;&#x6570;&#x636E;&#x6E90;&#x7684;&#x8BBE;&#x8BA1;&#x8BA9;React&#x7684;&#x7EC4;&#x4EF6;&#x4E4B;&#x95F4;&#x7684;&#x901A;&#x4FE1;&#x66F4;&#x52A0;&#x65B9;&#x4FBF;&#xFF0C;&#x540C;&#x65F6;&#x4E5F;&#x4FBF;&#x4E8E;&#x72B6;&#x6001;&#x7684;&#x7EDF;&#x4E00;&#x7BA1;&#x7406;</li>
</ul>
<h2 id="t34. Redux&#x6982;&#x5FF5;&#x89E3;&#x6790;">4. Redux&#x6982;&#x5FF5;&#x89E3;&#x6790; <a href="#t34. Redux&#x6982;&#x5FF5;&#x89E3;&#x6790;"> # </a></h2>
<h3 id="t44.1 Store">4.1 Store <a href="#t44.1 Store"> # </a></h3>
<ul>
<li><code>Store</code>&#x5C31;&#x662F;&#x4FDD;&#x5B58;&#x6570;&#x636E;&#x7684;&#x5730;&#x65B9;&#xFF0C;&#x4F60;&#x53EF;&#x4EE5;&#x628A;&#x5B83;&#x770B;&#x6210;&#x4E00;&#x4E2A;&#x5BB9;&#x5668;&#x3002;&#x6574;&#x4E2A;&#x5E94;&#x7528;&#x53EA;&#x80FD;&#x6709;&#x4E00;&#x4E2A;<code>Store</code></li>
<li>Redux &#x63D0;&#x4F9B;<code>createStore</code>&#x8FD9;&#x4E2A;&#x51FD;&#x6570;&#xFF0C;&#x7528;&#x6765;&#x751F;&#x6210;<code>Store</code><pre><code class="lang-js"><span class="hljs-keyword">import</span> { createStore } <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;redux&apos;</span>;
<span class="hljs-keyword">const</span> store = createStore(reducer);
</code></pre>
<blockquote>
<p>&#x4E0A;&#x9762;&#x4EE3;&#x7801;&#x4E2D;&#xFF0C;createStore&#x51FD;&#x6570;&#x63A5;&#x53D7;&#x53E6;&#x4E00;&#x4E2A;&#x51FD;&#x6570;&#x4F5C;&#x4E3A;&#x53C2;&#x6570;&#xFF0C;&#x8FD4;&#x56DE;&#x65B0;&#x751F;&#x6210;&#x7684;Store&#x5BF9;&#x8C61;&#x3002;</p>
</blockquote>
</li>
</ul>
<h3 id="t54.2 State">4.2 State <a href="#t54.2 State"> # </a></h3>
<p>Store&#x5BF9;&#x8C61;&#x5305;&#x542B;&#x6240;&#x6709;&#x6570;&#x636E;&#x3002;&#x5982;&#x679C;&#x60F3;&#x5F97;&#x5230;&#x67D0;&#x4E2A;&#x65F6;&#x70B9;&#x7684;&#x6570;&#x636E;&#xFF0C;&#x5C31;&#x8981;&#x5BF9;Store&#x751F;&#x6210;&#x5FEB;&#x7167;&#x3002;&#x8FD9;&#x79CD;&#x65F6;&#x95F4;&#x70B9;&#x7684;&#x6570;&#x636E;&#x96C6;&#x5408;&#xFF0C;&#x5C31;&#x53EB;&#x505A;State&#x3002; &#x5F53;&#x524D;&#x65F6;&#x523B;&#x7684;State&#xFF0C;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;<code>store.getState()</code>&#x62FF;&#x5230;&#x3002;</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { createStore } <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;redux&apos;</span>;
<span class="hljs-keyword">const</span> store = createStore(reducer);
<span class="hljs-keyword">const</span> state = store.getState();
</code></pre>
<blockquote>
<p>Redux &#x89C4;&#x5B9A;&#xFF0C; &#x4E00;&#x4E2A; State &#x5BF9;&#x5E94;&#x4E00;&#x4E2A; View&#x3002;&#x53EA;&#x8981; State &#x76F8;&#x540C;&#xFF0C;View &#x5C31;&#x76F8;&#x540C;&#x3002;&#x4F60;&#x77E5;&#x9053; State&#xFF0C;&#x5C31;&#x77E5;&#x9053; View &#x662F;&#x4EC0;&#x4E48;&#x6837;&#xFF0C;&#x53CD;&#x4E4B;&#x4EA6;&#x7136;&#x3002;</p>
</blockquote>
<h3 id="t64.3 Action">4.3 Action <a href="#t64.3 Action"> # </a></h3>
<p>State&#x7684;&#x53D8;&#x5316;&#xFF0C;&#x4F1A;&#x5BFC;&#x81F4;View&#x7684;&#x53D8;&#x5316;&#x3002;&#x4F46;&#x662F;&#xFF0C;&#x7528;&#x6237;&#x63A5;&#x89E6;&#x4E0D;&#x5230; State&#xFF0C;&#x53EA;&#x80FD;&#x63A5;&#x89E6;&#x5230;View
&#x6240;&#x4EE5;&#xFF0C;State&#x7684;&#x53D8;&#x5316;&#x5FC5;&#x987B;&#x662F; View&#x5BFC;&#x81F4;&#x7684;&#x3002;Action &#x5C31;&#x662F; View &#x53D1;&#x51FA;&#x7684;&#x901A;&#x77E5;&#xFF0C;&#x8868;&#x793A;State &#x5E94;&#x8BE5;&#x8981;&#x53D1;&#x751F;&#x53D8;&#x5316;&#x4E86;&#x3002; 
Action&#x662F;&#x4E00;&#x4E2A;&#x5BF9;&#x8C61;&#x3002;&#x5176;&#x4E2D;&#x7684;type&#x5C5E;&#x6027;&#x662F;&#x5FC5;&#x987B;&#x7684;&#xFF0C;&#x8868;&#x793A; Action &#x7684;&#x540D;&#x79F0;&#x3002;&#x5176;&#x4ED6;&#x5C5E;&#x6027;&#x53EF;&#x4EE5;&#x81EA;&#x7531;&#x8BBE;&#x7F6E;&#xFF0C;&#x793E;&#x533A;&#x6709;&#x4E00;&#x4E2A;&#x89C4;&#x8303;&#x53EF;&#x4EE5;&#x53C2;&#x8003;&#x3002;</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> action = {
  <span class="hljs-attr">type</span>: <span class="hljs-string">&apos;ADD_TODO&apos;</span>,
  <span class="hljs-attr">payload</span>: <span class="hljs-string">&apos;&#x5B66;&#x4E60;redux&apos;</span>
};
</code></pre>
<p>&#x4E0A;&#x9762;&#x4EE3;&#x7801;&#x4E2D;&#xFF0C;Action &#x7684;&#x540D;&#x79F0;&#x662F;<code>ADD_TODO</code>&#xFF0C;&#x5B83;&#x643A;&#x5E26;&#x7684;&#x4FE1;&#x606F;&#x662F;&#x5B57;&#x7B26;&#x4E32;<code>&#x5B66;&#x4E60;redux</code>&#x3002; 
&#x53EF;&#x4EE5;&#x8FD9;&#x6837;&#x7406;&#x89E3;&#xFF0C;Action&#x63CF;&#x8FF0;&#x5F53;&#x524D;&#x53D1;&#x751F;&#x7684;&#x4E8B;&#x60C5;&#x3002;&#x6539;&#x53D8;State&#x7684;&#x552F;&#x4E00;&#x529E;&#x6CD5;&#xFF0C;&#x5C31;&#x662F;&#x4F7F;&#x7528; Action&#x3002;&#x5B83;&#x4F1A;&#x8FD0;&#x9001;&#x6570;&#x636E;&#x5230; Store&#x3002;</p>
<h3 id="t74.4 Action Creator">4.4 Action Creator <a href="#t74.4 Action Creator"> # </a></h3>
<p>View&#x8981;&#x53D1;&#x9001;&#x591A;&#x5C11;&#x79CD;&#x6D88;&#x606F;&#xFF0C;&#x5C31;&#x4F1A;&#x6709;&#x591A;&#x5C11;&#x79CD; Action&#x3002;&#x5982;&#x679C;&#x90FD;&#x624B;&#x5199;&#xFF0C;&#x4F1A;&#x5F88;&#x9EBB;&#x70E6;&#x3002;&#x53EF;&#x4EE5;&#x5B9A;&#x4E49;&#x4E00;&#x4E2A;&#x51FD;&#x6570;&#x6765;&#x751F;&#x6210; Action&#xFF0C;&#x8FD9;&#x4E2A;&#x51FD;&#x6570;&#x5C31;&#x53EB; Action Creator&#x3002;</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> ADD_TODO = <span class="hljs-string">&apos;&#x6DFB;&#x52A0; TODO&apos;</span>;
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">addTodo</span>(<span class="hljs-params">text</span>) </span>{
  <span class="hljs-keyword">return</span> {
    <span class="hljs-attr">type</span>: ADD_TODO,
    text
  }
}

<span class="hljs-keyword">const</span> action = addTodo(<span class="hljs-string">&apos;&#x5B66;&#x4E60;Redux&apos;</span>);
</code></pre>
<blockquote>
<p>&#x4E0A;&#x9762;&#x4EE3;&#x7801;&#x4E2D;&#xFF0C;addTodo&#x51FD;&#x6570;&#x5C31;&#x662F;&#x4E00;&#x4E2A; Action Creator&#x3002;</p>
</blockquote>
<h3 id="t84.5 store.dispatch()">4.5 store.dispatch() <a href="#t84.5 store.dispatch()"> # </a></h3>
<p><code>store.dispatch()</code>&#x662F; View &#x53D1;&#x51FA; Action &#x7684;&#x552F;&#x4E00;&#x65B9;&#x6CD5;&#x3002;</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { createStore } <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;redux&apos;</span>;
<span class="hljs-keyword">const</span> store = createStore(reducer);

store.dispatch({
  <span class="hljs-attr">type</span>: <span class="hljs-string">&apos;ADD_TODO&apos;</span>,
  <span class="hljs-attr">payload</span>: <span class="hljs-string">&apos;&#x5B66;&#x4E60;Redux&apos;</span>
});
</code></pre>
<p>&#x4E0A;&#x9762;&#x4EE3;&#x7801;&#x4E2D;&#xFF0C;store.dispatch&#x63A5;&#x53D7;&#x4E00;&#x4E2A; Action &#x5BF9;&#x8C61;&#x4F5C;&#x4E3A;&#x53C2;&#x6570;&#xFF0C;&#x5C06;&#x5B83;&#x53D1;&#x9001;&#x51FA;&#x53BB;&#x3002; &#x7ED3;&#x5408; Action Creator&#xFF0C;&#x8FD9;&#x6BB5;&#x4EE3;&#x7801;&#x53EF;&#x4EE5;&#x6539;&#x5199;&#x5982;&#x4E0B;&#x3002;</p>
<pre><code class="lang-js">store.dispatch(addTodo(<span class="hljs-string">&apos;&#x5B66;&#x4E60;Redux&apos;</span>))
</code></pre>
<h3 id="t94.6 Reducer">4.6 Reducer <a href="#t94.6 Reducer"> # </a></h3>
<ul>
<li>Store &#x6536;&#x5230; Action &#x4EE5;&#x540E;&#xFF0C;&#x5FC5;&#x987B;&#x7ED9;&#x51FA;&#x4E00;&#x4E2A;&#x65B0;&#x7684; State&#xFF0C;&#x8FD9;&#x6837; View &#x624D;&#x4F1A;&#x53D1;&#x751F;&#x53D8;&#x5316;&#x3002;</li>
<li>&#x8FD9;&#x79CD; State &#x7684;&#x8BA1;&#x7B97;&#x8FC7;&#x7A0B;&#x5C31;&#x53EB;&#x505A; Reducer&#x3002; </li>
<li>Reducer &#x662F;&#x4E00;&#x4E2A;&#x7EAF;&#x51FD;&#x6570;&#xFF0C;&#x5B83;&#x63A5;&#x53D7;  &#x5F53;&#x524D; State &#x548C;Action&#x4F5C;&#x4E3A;&#x53C2;&#x6570;&#xFF0C;&#x8FD4;&#x56DE;&#x4E00;&#x4E2A;&#x65B0;&#x7684; State&#x3002;<pre><code class="lang-js"><span class="hljs-keyword">const</span> reducer = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">state, action</span>) </span>{
<span class="hljs-keyword">return</span> new_state;
};
</code></pre>
</li>
</ul>
<h2 id="t105.&#x7F16;&#x5199;Redux">5.&#x7F16;&#x5199;Redux <a href="#t105.&#x7F16;&#x5199;Redux"> # </a></h2>
<pre><code class="lang-js">
<span class="hljs-comment">/**
 * &#x521B;&#x5EFA;&#x4E00;&#x4E2A;Redux&#x4ED3;&#x5E93;&#x6765;&#x4FDD;&#x5B58;&#x6574;&#x4E2A;&#x72B6;&#x6001;&#x6811;
 * &#x6539;&#x53D8;&#x72B6;&#x6001;&#x6811;&#x7684;&#x552F;&#x4E00;&#x65B9;&#x6CD5;&#x662F;&#x8C03;&#x7528;store.dispatch&#x65B9;&#x6CD5;
 * &#x5728;&#x6574;&#x4E2A;&#x5E94;&#x7528;&#x4E2D;&#x53EA;&#x80FD;&#x6709;&#x4E00;&#x4E2A;&#x4ED3;&#x5E93;
 * &#x4E3A;&#x4E86;&#x6307;&#x5B9A;&#x72B6;&#x6001;&#x6811;&#x7684;&#x5404;&#x4E2A;&#x90E8;&#x5206;&#x5982;&#x4F55;&#x54CD;&#x5E94;action&#x7684;&#x53D8;&#x5316;&#xFF0C;&#x4F60;&#x53EF;&#x80FD;&#x4F7F;&#x7528;combineReducers&#x65B9;&#x6CD5;&#x628A;&#x591A;&#x4E2A;reducer&#x5408;&#x5E76;&#x4E3A;&#x4E00;&#x4E2A;&#x5355;&#x72EC;&#x7684;reducer
 * 
 * @param {Function} reducer &#x4E00;&#x4E2A;&#x901A;&#x8FC7;&#x5F53;&#x524D;&#x72B6;&#x6001;&#x5BF9;&#x8C61;&#x548C;&#x8981;&#x5904;&#x7406;&#x7684;action&#x8FD4;&#x56DE;&#x65B0;&#x7684;&#x72B6;&#x6001;&#x6811;&#x7684;&#x51FD;&#x6570;
 * @param {any} [preloadedState] &#x521D;&#x59CB;&#x72B6;&#x6001;&#x3002;&#x5728;&#x540C;&#x6784;&#x5E94;&#x7528;&#x4E2D;&#xFF0C;&#x4F60;&#x53EF;&#x80FD;&#x9700;&#x8981;&#x6307;&#x5B9A;&#x5B83;&#x4EE5;&#x5408;&#x5E76;&#x6765;&#x81EA;&#x670D;&#x52A1;&#x5668;&#x7684;&#x72B6;&#x6001;&#xFF0C;&#x6216;&#x8005;&#x4ECE;&#x4E00;&#x4E2A;&#x4EE5;&#x524D;&#x5E8F;&#x5217;&#x5316;&#x7684;&#x7528;&#x6237;&#x4F1A;&#x8BDD;&#x4E2D;&#x6062;&#x590D;. 
 * &#x5982;&#x679C;&#x4F60;&#x4F7F;&#x7528;&#x4E86;combineReducers,&#x6765;&#x4ECE;&#x6839;reducer&#x4E2D;&#x4EA7;&#x751F;&#x72B6;&#x6001;&#xFF0C;&#x8FD9;&#x5FC5;&#x987B;&#x662F;&#x4E00;&#x4E2A;&#x548C;combineReducer &#x7684;keys&#x76F8;&#x540C;&#x5F62;&#x72B6;&#x7684;&#x5BF9;&#x8C61;
 * @param {Function} [enhancer] &#x4ED3;&#x5E93;&#x7684;enhancer. &#x4F60;&#x53EF;&#x80FD;&#x9700;&#x8981;&#x6307;&#x5B9A;&#x8FD9;&#x4E2A;&#x53BB;&#x589E;&#x5F3A;&#x4ED3;&#x5E93;&#x7684;&#x80FD;&#x529B;&#x4EE5;&#x4F7F;&#x7528;&#x7B2C;&#x4E09;&#x65B9;&#x7684;&#x80FD;&#x529B;&#x6BD4;&#x5982;&#x4E2D;&#x95F4;&#x4EF6;
 * &#x65F6;&#x95F4;&#x65C5;&#x884C;&#xFF0C;&#x6301;&#x4E45;&#x5316;&#x7B49;&#x7B49;&#x3002;redux&#x81EA;&#x5E26;&#x7684;&#x552F;&#x4E00;&#x4E2D;&#x95F4;&#x4EF6;&#x662F;applyMiddleware
 * @returns {Store} &#x662F;&#x4E00;&#x4E2A;Redux&#x4ED3;&#x5E93;&#x8BA9;&#x4F60;&#x53EF;&#x4EE5;&#x8BFB;&#x53D6;&#x72B6;&#x6001;&#xFF0C;&#x6D3E;&#x53D1;action&#x5E76;&#x8BA2;&#x9605;&#x72B6;&#x6001;&#x53D8;&#x5316;
 */</span>

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createStore</span>(<span class="hljs-params">reducer,preloadedState,enhancer</span>) </span>{
    <span class="hljs-keyword">if</span> (enhancer) {
        <span class="hljs-keyword">return</span> enhancer(createStore)(reducer,preloadedState);
    }
    <span class="hljs-keyword">let</span> state=preloadedState;
    <span class="hljs-keyword">let</span> listeners=[];
    <span class="hljs-comment">/**
     * &#x8BFB;&#x53D6;&#x4ED3;&#x5E93;&#x7BA1;&#x7406;&#x7684;&#x72B6;&#x6001;&#x6811;
     * @returns {any} &#x5E94;&#x7528;&#x5F53;&#x524D;&#x7684;&#x72B6;&#x6001;&#x6811;
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getState</span>(<span class="hljs-params"></span>) </span>{
        <span class="hljs-keyword">return</span> state;
    }
    <span class="hljs-comment">/**
     * &#x589E;&#x52A0;&#x4E00;&#x4E2A;&#x53D8;&#x5316;&#x76D1;&#x542C;&#x51FD;&#x6570;&#x3002;&#x5B83;&#x5C06;&#x5728;&#x4EFB;&#x4F55;&#x6D3E;&#x53D1;&#x52A8;&#x4F5C;&#x7684;&#x65F6;&#x5019;&#x88AB;&#x8C03;&#x7528;
     * &#x72B6;&#x6001;&#x6811;&#x7684;&#x90E8;&#x5206;&#x6570;&#x636E;&#x53EF;&#x80FD;&#x4F1A;&#x53D1;&#x751F;&#x6F5C;&#x5728;&#x7684;&#x53D8;&#x5316;&#x3002;&#x4F60;&#x53EF;&#x80FD;&#x5728;&#x90A3;&#x4E2A;&#x65F6;&#x5019;&#x5728;&#x56DE;&#x8C03;&#x51FD;&#x6570;&#x4E2D;&#x8C03;&#x7528;getState&#x65B9;&#x6CD5;&#x4EE5;&#x83B7;&#x53D6;&#x6700;&#x65B0;&#x7684;&#x72B6;&#x6001;&#x3002;
     * &#x4F60;&#x53EF;&#x80FD;&#x4F1A;&#x5728;&#x76D1;&#x542C;&#x51FD;&#x6570;&#x91CC;&#x8C03;&#x7528;dispatch&#x65B9;&#x6CD5;&#xFF0C;&#x5B83;&#x4F1A;&#x5177;&#x5907;&#x4EE5;&#x4E0B;&#x6CE8;&#x610F;&#x4E8B;&#x9879;
     * 1. &#x8BA2;&#x9605;&#x4EC5;&#x4EC5;&#x5728;&#x6BCF;&#x4E00;&#x6B21;&#x8C03;&#x7528;&#x6BCF;&#x4E00;&#x4E2A;dispatch&#x65B9;&#x6CD5;&#x65F6;&#x88AB;&#x8BB0;&#x5F55;&#x5FEB;&#x7167;
     * &#x5982;&#x679C;&#x4F60;&#x5728;&#x76D1;&#x542C;&#x51FD;&#x6570;&#x88AB;&#x89E6;&#x53D1;&#x7684;&#x65F6;&#x5019;&#x8BA2;&#x9605;&#x6216;&#x53D6;&#x6D88;&#x8BA2;&#x9605;&#x7684;&#x8BDD;&#xFF0C;&#x8FD9;&#x5BF9;&#x5F53;&#x524D;&#x6B63;&#x5728;&#x5904;&#x7406;&#x4E2D;&#x7684;dispatch&#x6CA1;&#x6709;&#x4EFB;&#x4F55;&#x6548;&#x679C;
     * &#x5C3D;&#x7BA1;&#x5982;&#x6B64;&#xFF0C;&#x5728;&#x4E0B;&#x4E00;&#x6B21;dispatch&#x65B9;&#x6CD5;&#x7684;&#x8C03;&#x7528;&#x4E2D;&#xFF0C;&#x4E0D;&#x7BA1;&#x662F;&#x4E0D;&#x662F;&#x5185;&#x5D4C;&#xFF0C;&#x90FD;&#x5C06;&#x4F7F;&#x7528;&#x4E00;&#x4E2A;&#x6700;&#x65B0;&#x7684;&#x8BA2;&#x9605;&#x5217;&#x8868;
     * 
     * 2.&#x76D1;&#x542C;&#x51FD;&#x6570;&#x4E0D;&#x5E94;&#x8BE5;&#x9884;&#x671F;&#x6240;&#x6709;&#x7684;&#x72B6;&#x6001;&#x53D8;&#x5316;&#xFF0C;&#x56E0;&#x4E3A;&#x72B6;&#x6001;&#x53EF;&#x80FD;&#x5728;dispatch&#x4E2D;&#x88AB;&#x66F4;&#x65B0;&#x591A;&#x6B21;&#x3002; &#x5C3D;&#x7BA1;&#x5982;&#x6B64;&#xFF0C;&#x5728; dispatch&#x4E4B;&#x524D;&#x6CE8;&#x518C;&#x7684;&#x8BA2;&#x9605;&#x8005;&#x5C06;&#x4F1A;&#x4EE5;&#x6700;&#x65B0;&#x7684;&#x72B6;&#x6001;&#x8C03;&#x7528;
     * 
     * @param {*} listener  &#x6BCF;&#x4E00;&#x6B21;dispatch&#x65F6;&#x88AB;&#x8C03;&#x7528;&#x7684;&#x76D1;&#x542C;&#x51FD;&#x6570;
     * @returns {Function} &#x8FD4;&#x56DE;&#x4E00;&#x4E2A;&#x53EF;&#x4EE5;&#x79FB;&#x9664;&#x6B64;&#x76D1;&#x542C;&#x51FD;&#x6570;&#x7684;&#x51FD;&#x6570;
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">subscribe</span>(<span class="hljs-params">listener</span>) </span>{
        listeners.push(listener);
        <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
            <span class="hljs-keyword">const</span> index=listeners.indexOf(listener);
            listeners.splice(inddx,<span class="hljs-number">1</span>);
        }
    }

    <span class="hljs-comment">/**
     * &#x6D3E;&#x53D1;&#x4E00;&#x4E2A;&#x52A8;&#x4F5C;&#xFF0C;&#x8FD9;&#x662F;&#x89E6;&#x53D1;&#x72B6;&#x6001;&#x6539;&#x53D8;&#x7684;&#x552F;&#x4E00;&#x65B9;&#x5F0F;
     * &#x7528;&#x6765;&#x521B;&#x5EFA;&#x4ED3;&#x5E93;&#x7684;reducer&#x51FD;&#x6570;&#x5C06;&#x4F1A;&#x88AB;&#x8C03;&#x7528;&#xFF0C;&#x53C2;&#x6570;&#x662F;&#x5F53;&#x524D;&#x7684;&#x72B6;&#x6001;&#x6811;&#x548C;&#x7ED9;&#x5B9A;&#x7684;&#x52A8;&#x4F5C;&#x3002;&#x5B83;&#x7684;&#x8FD4;&#x56DE;&#x503C;&#x5C06;&#x4F1A;&#x88AB;&#x5F53;&#x4F5C;&#x4E0B;&#x4E00;&#x4E2A;&#x72B6;&#x6001;&#x6811;&#xFF0C;&#x6240;&#x6709;&#x7684;&#x76D1;&#x542C;&#x51FD;&#x6570;&#x4E5F;&#x4F1A;&#x88AB;&#x901A;&#x77E5;
     * 
     * &#x57FA;&#x672C;&#x5B9E;&#x73B0;&#x4E2D;&#x53EA;&#x652F;&#x6301;&#x7B80;&#x5355;&#x52A8;&#x4F5C;&#x5BF9;&#x8C61;&#x3002;&#x5982;&#x679C;&#x4F60;&#x60F3;&#x8981;&#x6D3E;&#x53D1;&#x4E00;&#x4E2A;Promise&#x3001;&#x4E00;&#x4E2A;Observerable&#x3001;&#x4E00;&#x4E2A;thunk&#x6216;&#x8005;&#x5176;&#x5B83;&#x7684;&#x4EFB;&#x4F55;&#x61C2;&#x7231;&#xFF0C;&#x4F60;&#x9700;&#x8981;&#x628A;&#x4F60;&#x521B;&#x5EFA;&#x4ED3;&#x5E93;&#x7684;&#x51FD;&#x6570;&#x5305;&#x88F9;&#x5230;&#x5BF9;&#x5E94;&#x7684;&#x4E2D;&#x95F4;&#x4EF6;&#x91CC;&#x3002;
     * &#x6BD4;&#x5982;&#xFF0C;&#x4F60;&#x53EF;&#x4EE5;&#x770B;&#x4E00;&#x4E0B;redux-thunk&#x5305;&#x3002;&#x751A;&#x81F3;&#x4E2D;&#x95F4;&#x4EF6;&#x6700;&#x540E;&#x901A;&#x8FC7;&#x8FD9;&#x4E2A;&#x65B9;&#x6CD5;&#x5C06;&#x4F1A;&#x6D3E;&#x53D1;&#x7B80;&#x5355;&#x5BF9;&#x8C61;&#x3002;
     * 
     * 
     * @param {*} action &#x4E00;&#x4E2A;&#x8868;&#x793A;&#x53D1;&#x751F;&#x4E86;&#x4EC0;&#x4E48;&#x7684;&#x7B80;&#x5355;&#x5BF9;&#x8C61;&#x3002;&#x4FDD;&#x6301;&#x52A8;&#x4F5C;&#x5E8F;&#x5217;&#x5316;&#x5C06;&#x4F1A;&#x662F;&#x4E00;&#x4E2A;&#x597D;&#x4E3B;&#x610F;&#xFF0C;&#x4EE5;&#x65B9;&#x4FBF;&#x4F60;&#x8FDB;&#x884C;&#x8BB0;&#x5F55;&#x548C;&#x56DE;&#x653E;&#x7528;&#x6237;&#x4F1A;&#x8BDD;&#x3002;&#x6216;&#x8005;&#x4F7F;&#x7528;&#x65F6;&#x95F4;&#x65C5;&#x884C;&#x5DE5;&#x5177;redux-devtools.&#x4E00;&#x4E2A;&#x52A8;&#x4F5C;&#x5FC5;&#x987B;&#x6709;&#x4E00;&#x4E2A;type&#x5C5E;&#x6027;&#x800C;&#x4E14;&#x4E0D;&#x80FD;&#x662F;undefine.&#x4F7F;&#x7528;&#x5B57;&#x7B26;&#x4E32;&#x5E38;&#x91CF;&#x8868;&#x793A;&#x52A8;&#x4F5C;&#x7C7B;&#x578B;&#x5C06;&#x4F1A;&#x662F;&#x4E2A;&#x597D;&#x4E3B;&#x610F;&#x3002;
     * @returns {object} &#x4E3A;&#x4E86;&#x65B9;&#x4FBF;&#xFF0C;&#x4F60;&#x6D3E;&#x53D1;&#x7684;&#x76F8;&#x540C;&#x7684;&#x52A8;&#x4F5C;&#x5BF9;&#x8C61;
     * &#x8BF7;&#x6CE8;&#x610F;&#xFF0C;&#x5982;&#x679C;&#x4F60;&#x4F7F;&#x7528;&#x4E00;&#x4E2A;&#x81EA;&#x5B9A;&#x4E49;&#x4E2D;&#x95F4;&#x4EF6;&#xFF0C;&#x4F60;&#x53EF;&#x80FD;&#x9700;&#x8981;&#x5305;&#x88F9; dispatch&#x53BB;&#x8FD4;&#x56DE;&#x522B;&#x7684;&#x4E1C;&#x897F;(&#x6BD4;&#x5982;&#x4F60;&#x7B49;&#x5F85;&#x7684;Promise)
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">dispatch</span>(<span class="hljs-params">action</span>) </span>{
        state=reducer(state,action);
        listeners.forEach(<span class="hljs-function"><span class="hljs-params">listener</span>=&gt;</span>listener())
    }
    dispatch({<span class="hljs-attr">type</span>:<span class="hljs-string">&apos;@@redux/INIT&apos;</span>});
    <span class="hljs-keyword">return</span> {
        dispatch,
        subscribe,
        getState
    }
}

</code></pre>
<h2 id="t116. Counter-Vanilla">6. Counter-Vanilla <a href="#t116. Counter-Vanilla"> # </a></h2>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;value&quot;</span><span class="hljs-attr">0</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;increment&quot;</span>&gt;</span>+<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;decrement&quot;</span>&gt;</span>+<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;incrementIfOdd&quot;</span>&gt;</span>&#x5947;&#x6570;+1/button&gt;
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;incrementAsync&quot;</span>&gt;</span>&#x5F02;&#x6B65;+1<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> {createStore} <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;../redux&apos;</span>;
<span class="hljs-keyword">const</span> INCREMENT=<span class="hljs-string">&apos;INCREMENT&apos;</span>;
<span class="hljs-keyword">const</span> DECREMENT = <span class="hljs-string">&apos;DECREMENT&apos;</span>;
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">reducer</span>(<span class="hljs-params">state=<span class="hljs-number">0</span>,action</span>)</span>{
    <span class="hljs-keyword">switch</span>(action.type){
        <span class="hljs-keyword">case</span> INCREMENT:
            <span class="hljs-keyword">return</span> state + <span class="hljs-number">1</span>;
        <span class="hljs-keyword">case</span> DECREMENT:
            <span class="hljs-keyword">return</span> state - <span class="hljs-number">1</span>;
        <span class="hljs-keyword">default</span>:
            <span class="hljs-keyword">return</span> state;
    }
}
<span class="hljs-keyword">let</span> store=createStore(reducer);
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">render</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">&apos;value&apos;</span>).innerHTML=store.getState();
}
store.subscribe(render);
<span class="hljs-built_in">console</span>.log(store.getState());
render();
<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">&apos;increment&apos;</span>).addEventListener(<span class="hljs-string">&apos;click&apos;</span>,<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    store.dispatch({<span class="hljs-attr">type</span>:INCREMENT});
});
<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">&apos;decrement&apos;</span>).addEventListener(<span class="hljs-string">&apos;click&apos;</span>,<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    store.dispatch({<span class="hljs-attr">type</span>:DECREMENT});
});
<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">&apos;incrementIfOdd&apos;</span>).addEventListener(<span class="hljs-string">&apos;click&apos;</span>,<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">if</span>(store.getState()%<span class="hljs-number">2</span>!=<span class="hljs-number">0</span>)
        store.dispatch({<span class="hljs-attr">type</span>:INCREMENT});
});
<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">&apos;incrementAsync&apos;</span>).addEventListener(<span class="hljs-string">&apos;click&apos;</span>,<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    setTimeout(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
        store.dispatch({<span class="hljs-attr">type</span>:INCREMENT});
    },<span class="hljs-number">1000</span>);
});
</code></pre>
<h2 id="t126. React Counter">6. React Counter <a href="#t126. React Counter"> # </a></h2>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React,{Component} <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;react&apos;</span>;
<span class="hljs-keyword">import</span> PropTypes <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;prop-types&apos;</span>;
<span class="hljs-keyword">import</span> counter <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;../reducers&apos;</span>;
<span class="hljs-keyword">import</span> {createStore} <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;../../redux&apos;</span>;
<span class="hljs-keyword">const</span> store=createStore(counter);
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Counter</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Component</span></span>{
    <span class="hljs-keyword">constructor</span>(props) {
        <span class="hljs-keyword">super</span>(props);
        <span class="hljs-keyword">this</span>.state={<span class="hljs-attr">value</span>:<span class="hljs-number">0</span>};
    }
    componentDidMount() {
        <span class="hljs-keyword">this</span>.unsubscribe=store.subscribe(<span class="hljs-function"><span class="hljs-params">()</span>=&gt;</span><span class="hljs-keyword">this</span>.setState({<span class="hljs-attr">value</span>:store.getState()}));
    }
    componentWillUnmount() {
        <span class="hljs-keyword">this</span>.unsubscribe();
    }
    render() {
        <span class="hljs-keyword">const</span> {value,onInrement,onDecrement}=<span class="hljs-keyword">this</span>.props;
        <span class="hljs-keyword">return</span> (
            <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{this.state.value}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span>=&gt;</span>store.dispatch({type:&apos;INCREMENT&apos;})}&gt;+<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span>=&gt;</span>store.dispatch({type:&apos;DECREMENT&apos;})}&gt;-<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{</span>
                    () =&gt;</span> {
                        if (this.state.value%2!=0)
                            store.dispatch({type: &apos;INCREMENT&apos;})
                    }
                }&gt;IncrementIfOdd<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{</span>
                    () =&gt;</span> {
                        setTimeout(() =&gt; {
                            store.dispatch({type:&apos;INCREMENT&apos;})
                        },1000);
                    }
                }&gt;IncrementAsync<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
        )
    }
}
</code></pre>
<h2 id="t137.actionCreator&#x4F18;&#x5316;&#x7ED3;&#x6784;">7.actionCreator&#x4F18;&#x5316;&#x7ED3;&#x6784; <a href="#t137.actionCreator&#x4F18;&#x5316;&#x7ED3;&#x6784;"> # </a></h2>
<pre><code class="lang-js">&#x251C;&#x2500;&#x2500; components
&#x2502;   &#x2514;&#x2500;&#x2500; Counter.js
&#x251C;&#x2500;&#x2500; index.js
&#x2514;&#x2500;&#x2500; store
    &#x251C;&#x2500;&#x2500; action-types.js
    &#x251C;&#x2500;&#x2500; actions
    &#x2502;   &#x2514;&#x2500;&#x2500; counter.js
    &#x251C;&#x2500;&#x2500; index.js
    &#x2514;&#x2500;&#x2500; reducers
        &#x2514;&#x2500;&#x2500; counter.js
</code></pre>
<p>actions.js</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> * <span class="hljs-keyword">as</span> types <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;../action-types&apos;</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
    add() {
        <span class="hljs-keyword">return</span> {<span class="hljs-attr">type</span>: types.INCREMENT};
    },
    minus() {
        <span class="hljs-keyword">return</span> {<span class="hljs-attr">type</span>: types.DECREMENT};
    }
}
</code></pre>
<h2 id="t148.bindActionCreator">8.bindActionCreator <a href="#t148.bindActionCreator"> # </a></h2>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> actions <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;../store/actions/counter&apos;</span>;
<span class="hljs-keyword">import</span> {bindActionCreator} <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;../../redux&apos;</span>;
<span class="hljs-keyword">let</span> newActions=bindActionCreator(actions,store.dispatch);

<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span>=&gt;</span>newActions.add()}&gt;+<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
&lt;button onClick={()=&gt;newActions.minus()}&gt;-<span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
</code></pre>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">actions,dispatch</span>) </span>{
    <span class="hljs-keyword">let</span> newActions={};
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> key <span class="hljs-keyword">in</span> actions) {
        newActions[key]=<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> dispatch(actions[key].apply(<span class="hljs-literal">null</span>,<span class="hljs-built_in">arguments</span>));
    }
    <span class="hljs-keyword">return</span> newActions;
}
</code></pre>
<h2 id="t159. combineReducers">9. combineReducers <a href="#t159. combineReducers"> # </a></h2>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">combineReducers</span>(<span class="hljs-params">reducers</span>) </span>{
    <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">state={},action</span>) </span>{
        <span class="hljs-keyword">return</span> <span class="hljs-built_in">Object</span>.keys(reducers).reduce(<span class="hljs-function">(<span class="hljs-params">newState,key</span>) =&gt;</span> {
            newState[key]=reducers[key](state[key],action);
            <span class="hljs-keyword">return</span> newState;
        },{});
    }
}
</code></pre>
<h2 id="t1610. react-redux">10. react-redux <a href="#t1610. react-redux"> # </a></h2>
<p>index.js</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> Provider <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;./Provider&apos;</span>;
<span class="hljs-keyword">import</span> connect <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;./connect&apos;</span>;
<span class="hljs-keyword">export</span>  {
    Provider,
    connect
}
</code></pre>
<p>context.js</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;react&apos;</span>
<span class="hljs-keyword">let</span> {Provider,Consumer}=React.createContext();
<span class="hljs-keyword">export</span> {
    Provider,
    Consumer
}
</code></pre>
<p>Provider</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React,{Component} <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;react&apos;</span>;
<span class="hljs-keyword">import</span> {Provider <span class="hljs-keyword">as</span> P} <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;./context&apos;</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Provider</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Component</span></span>{
    render() {
        <span class="hljs-keyword">return</span> (
            <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">P</span> <span class="hljs-attr">value</span>=<span class="hljs-string">{{store:this.props.store}}</span>&gt;</span>
                {this.props.children}
            <span class="hljs-tag">&lt;/<span class="hljs-name">P</span>&gt;</span></span>
        )
    }
}
</code></pre>
<p>connect</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React,{Component} <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;react&apos;</span>;
<span class="hljs-keyword">import</span> {Consumer} <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;./context&apos;</span>;
<span class="hljs-keyword">import</span> {bindActionCreators} <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;../redux&apos;</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">mapStateToProps,mapDispatchToProps</span>) </span>{
    <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">Component</span>) </span>{
        <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Proxy</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Component</span></span>{
            <span class="hljs-keyword">constructor</span>(props) {
                <span class="hljs-keyword">super</span>(props);
                <span class="hljs-keyword">this</span>.state=mapStateToProps(props.store.getState());
            }
            componentDidMount() {
                <span class="hljs-keyword">this</span>.unsubscribe=<span class="hljs-keyword">this</span>.props.store.subscribe(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
                    <span class="hljs-keyword">this</span>.setState(mapStateToProps(<span class="hljs-keyword">this</span>.props.store.getState()));
                });
            }
            componentWillUnmount() {
                <span class="hljs-keyword">this</span>.unsubscribe();
            }
            render() {
                <span class="hljs-keyword">let</span> actions={};
                <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> mapDispatchToProps==<span class="hljs-string">&apos;object&apos;</span>) {
                    actions=bindActionCreators(mapDispatchToProps,<span class="hljs-keyword">this</span>.props.store.dispatch);
                } <span class="hljs-keyword">else</span> {
                    actions=mapDispatchToProps(<span class="hljs-keyword">this</span>.props.store.dispatch);
                }
                <span class="hljs-keyword">return</span> &lt;Component {...this.state} {...actions}/&gt;
            }
        }
        return () =&gt; (
            &lt;Consumer&gt;
                {
                    value =&gt; (
                        &lt;Proxy store={value.store}/&gt;
                    )
                }
            &lt;/Consumer&gt;
        )
    }
}
</code></pre>

        <div class="copyright">Powered by <a href="https://github.com/jaywcjlove/idoc" target="_blank">idoc</a>. Dependence <a href="https://nodejs.org">Node.js</a> run.</div>
    </div>
    
</div>

<script src="https://cdn.bootcss.com/jquery/3.0.0/jquery.js"></script>
<script>
$('.warpper .page-toc ul ul li a').on('click',function(){
  $('.warpper .page-toc ul ul li a').removeClass('my-active')
  $(this).addClass('my-active')
})
  // if (!$('.understand-me').length) {
  //   var bar = $(window).height() - $('.navbar ').height() - $('.page-toc').position().top;
  //   var count = bar / 26 / 2;
  //   var barHeight = $('.page-toc').outerHeight();
  //   $('.page-toc li').eq(0).children('a').addClass('red');
  //   var arr = [];
  //   $("h1,h2,h3,h4,h5,h6").each(function () {
  //     arr.push($(this).position().top);
  //   });
  //   var timer
  //   function dark() {
  //     clearTimeout(timer)
  //      timer = setTimeout(function () {
  //      var top = Math.abs($('.page-toc > ul').position().top);
  //      var cur = $('.content').scrollTop();
  //      for (var i = arr.length; i >= 0; i--) {
  //        if (arr[i] <= cur) {
  //          break;
  //        }
  //      }
  //      if (i === -1) {
  //        i = 0;
  //      }
  //      $('.page-toc li a').removeClass('red');
  //      $('.page-toc li').eq(i).children('a').addClass('red');
  //      let height = $('.page-toc li').eq(i).position().top-$('.page-toc').height(); // 如果当前的offset出去了 回到中间可好？
  //      $('.page-toc').scrollTop(height+$('.page-toc').height()/2);
  //    },200)
  //   }

  //   $('.content').on('scroll', dark);
  // }
</script>
<style>

    /* ::-webkit-scrollbar{width:14px;}
    ::-webkit-scrollbar-track{background-color:transparent;}
    ::-webkit-scrollbar-thumb{background-color:transparent;}
    ::-webkit-scrollbar-thumb:hover {background-color:transparent}
    ::-webkit-scrollbar-thumb:active {background-color:transparent} */

    .page-toc > ul .red {
        background: #f3f3f3;
        z-index: 1;
        border-left: 3px solid #009a61;
        -webkit-transition: all .2s ease;
        transition: all .2s ease;
        color: #000
    }





</style>
</body>
</html>
